---
sidebar_position: 1
title: Identities
---

import Tabs from "@theme/Tabs"
import TabItem from "@theme/TabItem"

# Semaphore identities

In order to join a [Semaphore group](/glossary#group), a user must first create a [Semaphore identity](/glossary#identity).
A Semaphore identity contains three values generated with the identity:

- Private key
- Public key
- Commitment

To use and verify the identity, the identity owner (user) must know its private key.
To prevent fraud, the owner should keep their private key secret.

## Install package

In your code, use the [`@semaphore-protocol/identity`](https://github.com/semaphore-protocol/semaphore/tree/main/packages/identity) package to manage Semaphore identities.

<Tabs
  defaultValue="npm"
  groupId="package-managers"
  values={[
{label: 'npm', value: 'npm'},
{label: 'Yarn', value: 'yarn'},
{label: 'pnpm', value: 'pnpm'}
]}
>
  <TabItem value="npm">
    ```bash
    npm install @semaphore-protocol/identity
    ```
  </TabItem>

  <TabItem value="yarn">
    ```bash
    yarn add @semaphore-protocol/identity
    ```
  </TabItem>

  <TabItem value="pnpm">
    ```bash
    pnpm add @semaphore-protocol/identity
    ```
  </TabItem>
</Tabs>

:::info
Semaphore also provides `@semaphore-protocol/core`, which includes the functions of the following core packages: `@semaphore-protocol/identity`, `@semaphore-protocol/group`, `@semaphore-protocol/proof`.
:::

## Create identities

### Create random identities

To create a random identity, instantiate `Identity` without any parameters. For example:

```ts
import { Identity } from "@semaphore-protocol/identity"

const { privateKey, publicKey, commitment } = new Identity()
```

The new identity contains your private key, your public key, and its associated commitment, which serves as a public representation of the identity (similar to an Ethereum address).

### Create deterministic identities

If you pass a previously used private key or any secret value that acts as your private key as parameter, you can deterministically generate a Semaphore identity.

```ts
const identity1 = new Identity(privateKey)
// or
const identity2 = new Identity("secret-value")
```

:::tip
Building a system to save or recover secret values of Semaphore identities is nontrivial.
You may choose to delegate such functionality to existing wallets such as Metamask. For example:

1. In Metamask, a user signs a message with the private key of their Ethereum account.
2. In your application, the user creates a deterministic identity with the signed message that acts as your Semaphore private key.
3. The user can now recreate their Semaphore identity whenever they want by signing the same message with their Ethereum account in Metamask.
   :::

:::warning Privacy risk
If a user signs the **same message** on multiple websites using MetaMask, all those websites will be able to **generate the same Semaphore identity**. This undermines anonymity and may allow third parties to **link identities across platforms** or even **gain control over a user's identity**.\
To mitigate this, encourage users to sign **unique messages per application** or implement safeguards that detect and warn about reuse.
:::

## Sign and verify messages

Semaphore V4 uses asymmetric cryptography and in particular EdDSA to generate the identity keys. It is therefore also possible to sign messages and verify their signatures.

### Sign a message

Any Semaphore identity can sign a message by simply passing a string, number or buffer.

```ts
const message = "Hello World"

const signature = identity1.signMessage(message)
```

### Verify a signature

After a message is signed, anyone can verify the signature using the message itself, the signature, and the signer's public key.

```ts
// Static method.
Identity.verifySignature(message, signature, identity1.publicKey)
```

## Export and import an identity

A Semaphore Identity can be exported and then imported later for reuse.

### Export an identity

Returns the private key encoded as a base64 string.

```ts
import { Identity } from "@semaphore-protocol/identity"

const identity = new Identity()

const privateKey = identity.export()
```

### Import an identity

Returns a Semaphore identity based on a private key encoded as a base64 string.

```ts
import { Identity } from "@semaphore-protocol/identity"

const identity = new Identity()

const privateKey = identity.export()

const identity2 = Identity.import(privateKey)
```
